package com.htfyun.eink.pw.core.ctrl;

import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.Display;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.htfyun.eink.pw.core.IEinkPWCoreController;
import com.htfyun.eink.pw.core.IImeStateListener;
import com.htfyun.eink.pw.core.IOnDrawListener;
import com.htfyun.eink.pw.core.IPointerEventListener;
import com.htfyun.eink.pw.core.enums.PWA2Gate;
import com.htfyun.eink.pw.core.enums.PWBmpType;
import com.htfyun.eink.pw.core.enums.PWDataMode;
import com.htfyun.eink.pw.core.enums.PWDisplayMode;

public class PWCoreController {

    @NonNull
    private final IEinkPWCoreController controller;

    private PWCoreController() {
        controller = PWCoreFactoryHelper.getPWCoreController();
    }

    private static class SingletonInstance {
        private static final PWCoreController INSTANCE = new PWCoreController();
    }

    public static PWCoreController getInstance() {
        return SingletonInstance.INSTANCE;
    }

    ///////////////////////////////////
    public void initForPw() {
        controller.initForPw();
    }

    public void deinitForPw() {
        controller.deinitForPw();
    }

    /**
     * 更新 pw bmp
     *
     * @param dirty       需要更新的那部分 rect
     * @param displayMode 显示模式 {@link PWDisplayMode}
     * @param a2Gate      {@link PWA2Gate} 如果 {@param dataMode}  是 A16, gate 就是锐化等级。如果没有锐化，需要设置为 0XFF.
     */
    public void updateRectForPw(@NonNull Rect dirty, PWDisplayMode displayMode, PWDataMode dataMode, PWA2Gate a2Gate) {
        postRectForPw(dirty, PWBmpType.BMP_TYPE_PW.getValue(), displayMode.getValue(), dataMode.getValue(), a2Gate.getValue());
    }

    /**
     * 更新 host bmp
     *
     * @param dirty       需要更新的那部分 rect
     * @param displayMode 显示模式 {@link PWDisplayMode}
     * @param dataMode    数据模式 {@link PWDataMode},
     * @param a2Gate      {@link PWA2Gate} 如果 {@param dataMode}  是 A16, gate 就是锐化等级。如果没有锐化，需要设置为 0XFF.
     */
    public void updateRectForHost(@NonNull Rect dirty, PWDisplayMode displayMode, PWDataMode dataMode, PWA2Gate a2Gate) {
        postRectForPw(dirty, PWBmpType.BMP_TYPE_HOST.getValue(), displayMode.getValue(), dataMode.getValue(), a2Gate.getValue());
    }

    public void postRectForPw(@NonNull Rect dirty, int bmpType, int displayMode, int dataMode, int a2Gate) {
        controller.postRectForPw(dirty, bmpType, displayMode, dataMode, a2Gate);
    }

    public void updatePwCanvasRotation(@NonNull Display display) {
        Point point = new Point();
        display.getRealSize(point);
        int displayRotation = display.getRotation() * 90;
        displayRotation += getHWRotation();
        if (displayRotation >= 360) {
            displayRotation -= 360;
        }
        updatePwCanvasRotation(displayRotation, point.x, point.y);
    }

    private void updatePwCanvasRotation(int rotation, int screenWidth, int screenHeight) {
        controller.updatePwCanvasRotation(rotation, screenWidth, screenHeight);
    }

    private int getHWRotation() {
        return controller.getHWRotation();
    }

    public void setPWViewOffsetXY(@NonNull Bitmap bmp, int offsetX, int offsetY) {
        controller.setPWViewOffsetXY(bmp, offsetX, offsetY);
    }

    public void setHostBmpOffsetXY(@NonNull Bitmap bmp, int offsetX, int offsetY) {
        controller.setHostBmpOffsetXY(bmp, offsetX, offsetY);
    }

    public void updatePWProperty() {
        controller.updatePWProperty();
    }

    public void setPWAction(int action) {
        controller.setPWAction(action);
    }

    public void setPointerEventListenerForView(@Nullable View view, @Nullable IPointerEventListener listener) {
        controller.setPointerEventListenerForView(view, listener);
    }

    public void setOnDrawListenerForView(@Nullable View view, @Nullable IOnDrawListener listener) {
        controller.setOnDrawListenerForView(view, listener);
    }

    void registerImeStateListener(@NonNull IImeStateListener listener) {
        controller.registerImeStateListener(listener);
    }

    void unregisterImeStateListener(@NonNull IImeStateListener listener) {
        controller.unregisterImeStateListener(listener);
    }

    //////////////////////////////
    //以下与 pw 手写无关.

    public void setEinkUpdateModeWithView(@NonNull View view, int dataMode, int dispMode) {
        controller.setEinkUpdateModeWithView(view, dataMode, dispMode);
    }

    void setValueAnimatorDurationScale(float durationScale) {
        controller.setValueAnimatorDurationScale(durationScale);
    }

    @NonNull
    public String getSystemProperties(String key) {
        return controller.getSystemProperties(key);
    }

    public void setSystemProperties(String key, String val) {
        controller.setSystemProperties(key, val);
    }
    //以上与 pw 手写无关.
    //////////////////////////////
}
